import sys
from PyQt5.QtWidgets import QApplication, QWidget, QPushButton, QMessageBox
from PyQt5.QtCore import QCoreApplication, QObject, Qt, pyqtSignal, pyqtSlot

class Example(QWidget):
    str_signal = pyqtSignal(str)  # 信号必须在类中定义，此处定义一个str参数类型的信号
    list_signal = pyqtSignal(list)  # list参数类型的信号
    multi_signal = pyqtSignal([int, str], [str])  # 多重载版本信号，包含一个带int和str类型参数的信号，以及一个str类型的参数
    def __init__(self):
        super().__init__()
        self.initUI()

    def initUI(self):
        self.setGeometry(100, 100, 300, 400)

        btn = QPushButton('Button', self)
        btn.resize(btn.sizeHint())

        btn.clicked.connect(QCoreApplication.instance().quit)
        self.str_signal.connect(self.show_help)  # 将str_signal信号绑定响应函数
        self.list_signal.connect(self.show_list)
        self.multi_signal[int, str].connect(self.show_double_args)  # 重载信号，需要单独实现各自的信号连接函数
        self.multi_signal[str].connect(self.show_single_args)
        self.show()

    def show_help(self, msg):
        QMessageBox.information(self, "", msg)

    def show_list(self, list_msg):
        for msg in list_msg:
            self.show_help(msg)

    def show_double_args(self, arg_int, arg_str):
        print("The int is : %d, the string is : %s" % (arg_int, arg_str))

    def show_single_args(self, args):
        print("The single argument is : ", args)

    def keyPressEvent(self, event):  # 重写键盘事件，在按键事件发生时自动调用
        if event.key() == Qt.Key_Escape:
            print("Get Escape Key, Exiting.")
            self.close()
        elif event.key() == Qt.Key_F1:
            self.str_signal.emit("Hello, This is help message.")  # 利用str_signal对象发送信号
        elif event.key() == Qt.Key_F2:
            self.list_signal.emit(["A", "B", "C"])
        elif event.key() == Qt.Key_F3:  # 重载信号，需要单独实现各自的信号发送
            # self.multi_signal[int, str].emit(123, "Double_args_Test")
            self.multi_signal.emit(123, "Double_args_Test")  # 可以省略 [int, str], 因为这是默认重载对象
        elif event.key() == Qt.Key_F4:
            self.multi_signal[str].emit("Single_arg_Test")
            # self.multi_signal.emit("Single_arg_Test")  # 错误，不可省略，因为默认类型需要两个参数


if __name__ == '__main__':
    app = QApplication(sys.argv)
    win = Example()
    sys.exit(app.exec_())
